/*
 * Copyright 2025 the original author or authors.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.openrewrite.groovy;

import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.Phases;
import org.jspecify.annotations.Nullable;

import java.security.CodeSource;

/**
 * The CompilationUnit collects all compilation data as it is generated by the compiler system.
 * You can use this object to add additional source units to the compilation, or force the
 * compilation to be run again (to affect only the deltas).
 * <p>
 * You can also add PhaseOperations to this compilation using the addPhaseOperation method.
 * This is commonly used when you want to wire a new AST Transformation into the compilation.
 *
 * @implNote Excludes AST transformations like replacing static imports by literals.
 */
public class LessAstTransformationsCompilationUnit extends CompilationUnit {

    private static final int CONVERT_ENUM_OPERATION = 0;
    private static final int STATIC_IMPORT_OPERATION = 0;

    private int conversionOperation = 0;
    private int semanticAnalysisOperation = 0;

    public LessAstTransformationsCompilationUnit(CompilerConfiguration configuration, @Nullable CodeSource codeSource, GroovyClassLoader loader, GroovyClassLoader transformLoader) {
        super(configuration, codeSource, loader, transformLoader);
        // Override the standard `ResolveVisitor`, which otherwise inlines any annotation property values
        this.resolveVisitor = new NoInlineAnnotationTransformationResolveVisitor(this);
    }

    @Override
    public void addPhaseOperation(IPrimaryClassNodeOperation op, int phase) {
        if (phase == Phases.CONVERSION) {
            if (conversionOperation++ == CONVERT_ENUM_OPERATION) {
                // we don't want to register the `EnumVisitor` operation
                return;
            }
        } else if (phase == Phases.SEMANTIC_ANALYSIS) {
            if (semanticAnalysisOperation++ == STATIC_IMPORT_OPERATION) {
                // we don't want to register the `StaticImportVisitor` operation
                return;
            }
        }
        super.addPhaseOperation(op, phase);
    }
}
